package com.dingwen.rabpro.config;

import com.dingwen.rabpro.constant.RabbitConstant;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 * rabbitmq 配置类 <br>
 * <p>
 *     fanout模式交换机、延迟队列、死信队列
 * </p>
 *
 * @author dingwen
 * 2021.06.17 10:36
 */
@Configuration
@SuppressWarnings("ALL")
public class RabbitmqConfigurationFanoutAndDirect {

    /**
     * 声明fanout模式的交换机
     *
     * @return {@link FanoutExchange}
     */
    @Bean
    public FanoutExchange fanoutExchange() {
        // 持久化、关闭自动删除
        return ExchangeBuilder.fanoutExchange(RabbitConstant.FANOUT_EXCHANGE_NAME)
                .durable(Boolean.TRUE)
                .build();
    }

    /**
     * 死信交换机
     *
     * @return {@link DirectExchange}
     */
    @Bean
    public DirectExchange directExchange() {
        return ExchangeBuilder.directExchange(RabbitConstant.DIRECT_EXCHANGE_NAME_DEAD)
                .durable(Boolean.TRUE)
                .build();
    }

    /**
     * 死信队列 <br>
     * <p>排他队列: 只有自己可见的队列，不允许其他队列访问</p>
     * <p>特点：</p>
     * <ol>
     *     <li>只对首次声明它的连接可见</li>
     *     <li>断开连接及自动删除</li>
     * </ol>
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue deadQueue() {
        return QueueBuilder.durable(RabbitConstant.DIRECT_QUEUE_DEAD_NAME)
                // 声明为排他队列
//                .exclusive()
                .build();
    }

    /**
     * 死信队列绑定
     *
     * @return {@link Binding}
     */
    @Bean
    public Binding deadBinding() {
        return BindingBuilder.bind(deadQueue())
                .to(directExchange())
                .with(RabbitConstant.DIRECT_QUEUE__ROUTE_DEAD);
    }

    /**
     * 短信任务队列
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue smsQueue() {
        return QueueBuilder.durable(RabbitConstant.FANOUT_QUEUE_SMS_NAME)
                .build();
    }

    /**
     * 邮件任务队列
     *
     * @return {@link Queue}
     */
    @Bean
    public Queue emailQueue() {
        // 持久化、排他性队列、关闭自动删除

        // TTL队列测试
        Map<String, Object> args = new HashMap<>(3);
        // 整形 毫秒
        args.put("x-message-ttl", 5000);

        // 绑定死信交换机
        args.put("x-dead-letter-exchange", RabbitConstant.DIRECT_EXCHANGE_NAME_DEAD);
        args.put("x-dead-letter-routing-key", RabbitConstant.DIRECT_QUEUE__ROUTE_DEAD);
        return QueueBuilder.durable(RabbitConstant.FANOUT_QUEUE_EMAIL_NAME)
                .withArguments(args)
                .build();
    }

    /**
     * 短信队列绑定到交换机
     *
     * @return {@link Binding}
     */
    @Bean
    public Binding smsBinding() {
        return BindingBuilder.bind(smsQueue()).to(fanoutExchange());
    }

    /**
     * 邮箱队列绑定到交换机
     *
     * @return {@link Binding}
     */
    @Bean
    public Binding emailBinding() {
        return BindingBuilder.bind(emailQueue()).to(fanoutExchange());
    }

}
